﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Windows;
using P2PChat.Client.UI;
using System.Threading;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using P2PChat.Client.Images;

namespace P2PChat.Client.Data
{
    public static class ChatSession
    {
        public static Dictionary<int, XElement> Sessions = new Dictionary<int, XElement>();
        public static Dictionary<int, WinChat> Windows = new Dictionary<int, WinChat>();

        private static int sessionCount = 1;
        public static int SessionCount { get { return sessionCount; } }
        private static Mutex SessionLock = new Mutex();

        public static bool SessionValidate(int num)
        {
            return Sessions[num] != null;
        }

        /// <summary>
        /// 申请一个新的会话
        /// </summary>
        /// <returns>申请到的SessionNumber</returns>
        public static int NewSession()
        {
            lock (SessionLock)
            {
                sessionCount++;
            }
            Sessions[sessionCount] = new XElement("ChatSession");
            return sessionCount;
        }

        /// <summary>
        /// 向某个会话中添加聊天成员
        /// </summary>
        /// <param name="session"></param>
        /// <param name="guid"></param>
        public static void AddMember(int session, Guid guid)
        {
            if (session == 0)
            {
                return;
            }
            else
            {
                int remotePort = -1; string remoteIp = "";
                try
                {
                    // 从服务器搜索用户的地址信息
                    MemoryStream ms = new MemoryStream();
                    BinaryFormatter bf = new BinaryFormatter();
                    bf.Serialize(ms, new P2PChat.Data.NetPacket()
                    {
                        Tag = P2PChat.Data.PacketTag.GetValue,
                        Content = new P2PChat.Data.Packets.GetUserIPEndPointPacket()
                        {
                            RemoteUserId = guid,
                        },
                    });

                    using (System.Net.Sockets.TcpClient client = new System.Net.Sockets.TcpClient())
                    {
                        client.Connect(GlobalConfig.ServerHost, GlobalConfig.ServerPort);
                        client.Client.Send(ms.GetBuffer());

                        P2PChat.Data.NetPacket p = bf.Deserialize(client.GetStream()) as P2PChat.Data.NetPacket;
                        P2PChat.Data.Packets.GetUserIPEndPointPacket pContent = p.Content as P2PChat.Data.Packets.GetUserIPEndPointPacket;
                        if (pContent.Port == -1)
                        {
                            throw new Exception("用户不在线!");
                        }

                        remoteIp = pContent.IPAddress;
                        remotePort = pContent.Port;
                    }

                    if (ChatSession.Sessions[session].Element("MemberList") == null) { ChatSession.Sessions[session].Add(new XElement("MemberList")); }
                    if (ChatSession.Sessions[session].Element("MemberList").Elements("Member").Count(x => x.Attribute("GUID").Value == guid.ToString()) > 0)
                    {
                        ChatSession.Sessions[session].Element("MemberList").Elements("Member").First(x => x.Attribute("GUID").Value == guid.ToString()).Remove();
                    }
                    ChatSession.Sessions[session].Element("MemberList").Add(new XElement("Member",
                        new XAttribute("GUID", guid.ToString()),
                        new XElement("IPEndPoint", 
                            new XElement("IPAddress", remoteIp),
                            new XElement("Port", remotePort))));
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
        }

        public static void ShowWindow(int session)
        {
            if (Windows.ContainsKey(session))
            {
                Windows[session].Show();
            }
            else
            {
                Windows[session] = new WinChat();
                Windows[session].SessionNumber = session;
                if (Sessions[session].Element("MemberList") == null) throw new Exception("该会话中没有任何成员!");
                foreach (XElement e in Sessions[session].Element("MemberList").Elements("Member"))
                {
                    if (FriendList.List.Elements("Group").Elements("Friend").Elements("PersonalInfo").Where(x =>
                        e.Attribute("GUID").Value == x.Attribute("GUID").Value).Count() > 0)
                    {
                        XElement friend = FriendList.List.Elements("Group").Elements("Friend").Elements("PersonalInfo").First(x =>
                            e.Attribute("GUID").Value == x.Attribute("GUID").Value);
                        Members_Portrait por = new Members_Portrait();
                        por.UserName = friend.Element("Nickname").Value;
                        por.img_Portrait.Source = ResourseImaging.GetPortrait(int.Parse(friend.Element("Portrait").Value));
                        Windows[session].MemberPanelChildren.Insert(0, por);
                    }
                }
                
                Windows[session].Show();
            }
        }

        
    }

    public enum SessionType
    {
        Single,
        Multi,
    }
}
